<?php

/**
 * Admin module bootstrap
 *
 * @author     Mon Zafra <monzee at gmail>
 * @copyright  (c)2009 Mon Zafra
 * @category   Mz
 * @package    modules
 * @subpackage admin
 * @license    http://mz-project.googlecode.com/svn/trunk/LICENSE    MIT License
 * @version    SVN: $Id: Bootstrap.php 47 2009-05-28 17:56:56Z monzee $
 */
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initAccessManager()
    {
        $this->getResourceLoader()
             ->addResourceType('actionhelper', 'controllers/helpers/', 'Helper');

        if (!Zend_Controller_Action_HelperBroker::hasHelper('AccessManager')) {
            $opts = self::getConfig('accessManager');
            $accessManager = new Admin_Helper_AccessManager($opts);
            Zend_Controller_Action_HelperBroker::addHelper($accessManager);
        }
    }

    protected function _initDoctrine()
    {
        if (@!class_exists('Doctrine', true)) {
            return;
        }

        $manager = Doctrine_Manager::getInstance();
        $config = self::getConfig('doctrine')->toArray();

        $dsn = $this->_generateDsn($config['adapter'], $config['params']);

        $manager->openConnection($dsn);

        $manager->setAttribute(Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
        $manager->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
        $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_TABLES);
        $manager->setAttribute(Doctrine::ATTR_MODEL_LOADING,
            Doctrine::MODEL_LOADING_CONSERVATIVE);

        return $manager;
    }

    protected function _initDoctrineCLI()
    {
        if (empty($_SERVER['argv'])) {
            return;
        }

        $this->bootstrap('Doctrine');
        $modPath = dirname(__FILE__);
        $options = array(
            'data_fixtures_path' => $modPath . '/data/doctrine/fixtures',
            'models_path'        => $modPath . '/models/Doctrine',
            'migrations_path'    => $modPath . '/data/doctrine/migrations',
            'sql_path'           => $modPath . '/data',
            'yaml_schema_path'   => $modPath . '/data/doctrine/schema',
            'generate_models_options' => array(
                'generateTableClasses' => true,
                'baseClassPrefix' => 'Base_',
                'baseClassesDirectory' => 'Base',
                'classPrefix' => 'Admin_Model_Doctrine_',
                'phpDocName' => 'Mon Zafra',
                'phpDocEmail' => 'monzee at gmail',
                'phpDocPackage' => 'modules',
                'phpDocSubpackage' => 'admin'
            )
        );

        $manager = $this->getResource('Doctrine');
        $manager->setAttribute(Doctrine::ATTR_MODEL_LOADING,
            Doctrine::MODEL_LOADING_AGGRESSIVE
        );

        return new Doctrine_Cli($options);
    }

    public function preDispatch()
    {
        // Use own layout
        $app = $this->getApplication();
        if ($app->hasResource('layout')) {
            $layout = $app->getResource('layout');
            $layout->enableLayout();
        } else {
            $layout = Zend_Layout::getMvcInstance();
            if (null === $layout) {
                $layout = Zend_Layout::startMvc();
            }
        }
        $layout->setLayoutPath(dirname(__FILE__) . '/layouts')
               ->setLayout('admin');
    }

    static protected $_config;
    /**
     *
     * @param mixed $key
     * @return Zend_Config
     */
    static public function getConfig($key = null)
    {
        if (null === self::$_config) {
            $configFile = dirname(__FILE__) . '/config.ini';
            if (!file_exists($configFile)) {
                throw new Exception('Admin module config file does not exist!');
            }
            self::$_config = new Zend_Config_Ini($configFile, 'admin');
        }
        return $key === null ? self::$_config : self::$_config->$key;
    }


    static protected $_adapter;
    /**
     *
     * @return Zend_Db_Adapter_Abstract
     */
    static public function getDbAdapter()
    {
        if (null === self::$_adapter) {
            $default = Zend_Db_Table_Abstract::getDefaultAdapter();
            $config = self::getConfig('db');
            if (null === $config) {
                self::$_adapter = $default;
            } else {
                $config = $config->toArray();
                if (isset($config['useDefault']) && $config['useDefault']) {
                    self::$_adapter = $default;
                } else {
                    $adapter = $config['adapter'];
                    $params = $config['params'];
                    self::$_adapter = Zend_Db::factory($adapter, $params);
                }
            }
        }
        return self::$_adapter;
    }

    static protected $_logger;
    /**
     * Log stuff to firebug. Turn this off by setting self::$_logger to false.
     * 
     * @param mixed $msg
     * @param int   $level
     * @return Zend_Log|bool Returns false if logging is disabled.
     */
    static public function log($msg = null, $level = Zend_Log::INFO)
    {
        if (false === self::$_logger) {
            return false;
        }
        if (null === self::$_logger) {
            $writer = new Zend_Log_Writer_Firebug();
            self::$_logger = new Zend_Log($writer);
        }
        if (func_num_args() == 0) {
            return self::$_logger;
        }
        return call_user_func(array(self::$_logger, 'log'), $msg, $level);
    }

    static public function disableLogging($disabled = true)
    {
        if ($disabled) {
            self::$_logger = false;
        } else if (false === self::$_logger) {
            self::$_logger = null;
        }
    }

    protected function _generateDsn($adapter, $params)
    {
        $adapter = strtolower($adapter);
        $params = array_change_key_case($params, CASE_LOWER);
        $username = null;
        $password = null;

        if ('pdo_' == substr($adapter, 0, 4)) {
            $adapter = substr($adapter, 4);
        }

        if ('sqlite' == $adapter) {
            $path = pathinfo($params['dbname']);
            $dsn = 'sqlite:' . realpath($path['dirname'])
                 . DIRECTORY_SEPARATOR . $path['basename'];
            unset($params['dbname']);
        } else {
            $dsn = $adapter
                 . (isset($params['dbsyntax'])
                    ? '(' . $params['dbsyntax'] . ')://'
                    : '://');
            unset($params['dbsyntax']);

            if (isset($params['username'])) {
                $username = $params['username'];
                $dsn .= urlencode($username);
                unset($params['username']);
                if (isset($params['password'])) {
                    $password = $params['password'];
                    $dsn .= ':' . urlencode($password);
                    unset($params['password']);
                }
                $dsn .= '@';
            }

            if (isset($params['host'])) {
                $hostSpec = isset($params['port'])
                          ? $params['host'] . ':' . $params['port']
                          : $params['host'];
                $dsn .= (isset($params['protocol'])
                         ? $params['protocol'] . '+' . $hostSpec
                         : $hostSpec)
                     .  '/';
                unset($params['host'], $params['port'], $params['protocol']);
            } else {
                $dsn .= 'localhost/';
            }

            if (isset($params['dbname'])) {
                $dsn .= urlencode($params['dbname']);
                unset($params['dbname']);
            }
        }

        if (!empty($params)) {
            $options = array();
            foreach ($params as $option => $value) {
                $options[] = $option . '=' . urlencode($value);
            }
            $dsn .= '?' . implode('&', $options);
        }
        
        return array($dsn, $username, $password);
    }

}
